/**
 * 
 */
package jpb;

import java.io.File;

/**
 * Default entry points into JVM as specified in {@link EntryPoint}.
 * 
 * 
 * @author Dariusz Kordonski
 */
public abstract class DefaultEntryPoint implements EntryPoint {

    /**
     * New class entry point for given <tt>className</tt>.
     *
     * @param className name of the class to use as a 'main' class
     * @return new class entry point
     */
    public static EntryPoint mainClass(String className) {
        return new ClassEntryPoint(className);
    }

    /**
     * Create new class entry point for <code>clazz</code>,
     * using its name.
     *
     * @param clazz class instance to use for starting the new Java process
     * @return new class entry point
     */
    public static DefaultEntryPoint mainClass(Class<?> clazz) {
        return new ClassEntryPoint(clazz.getName());
    }

    /**
     * New JAR entry point for given JAR file.
     *
     * @param jarFile JAR file to use
     * @return new JAR entry point
     */
    public static DefaultEntryPoint jar(File jarFile) {
        return new JarEntryPoint(jarFile);
    }


    private static class ClassEntryPoint extends DefaultEntryPoint {
        private final String className;
        ClassEntryPoint(String cn) {
            this.className = cn;
        }
        @Override
        public boolean isClassEntryPoint() { return true; }
        @Override
        public String className() { return this.className; }
    }


    private static class JarEntryPoint extends DefaultEntryPoint {
        private final File jarFile;
        JarEntryPoint(File jf) {
            this.jarFile = jf;
        }

        @Override
        public boolean isJarEntryPoint() { return true; }
        @Override
        public File jarFile() { return this.jarFile; }
    }



    private DefaultEntryPoint() {}

    /**
     * Checks if this instance of <code>EntryPoint</code> represents a
     * class entry point. In such case {@link #className()} should return
     * a valid class name and {@link #jarFile()} should throw
     * {@link IllegalStateException}.
     *
     * @return <code>true</code>, if this is a class entry point
     */
    public boolean isClassEntryPoint() { return false; }


    /**
     * Checks if this instance of <code>EntryPoint</code> represents a
     * JAR entry point. In such case {@link #jarFile()} should return
     * a valid, existing JAR file, and {@link #className()} should throw
     * {@link IllegalStateException}.
     *
     * @return <code>true</code>, if this is a JAR entry point
     */
    public boolean isJarEntryPoint()   { return false; }
    
    
    /**
     * Class name of this entry point.
     * 
     * @return class name of this entry point, given that it is a class entry point
     * @throws IllegalStateException if this is not a class entry point
     */
    public String className() {
        throw new IllegalStateException("className is invalid property of " + getClass().getName());
    }
    
    /**
     *  JAR file of this entry point, given it is a JAR entry point.
     * 
     * @return JAR file of this entry point
     * @throws IllegalStateException if this is not a JAR entry point
     */
    public File jarFile() {
        throw new IllegalStateException("jarFile is invalid property of " + getClass().getName());
    }
}
